package com.mlk.rbac.Service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.mlk.core.constants.Constant;
import com.mlk.core.exception.ParamException;
import com.mlk.core.util.ServerResponse;
import com.mlk.core.util.SessionUtils;
import com.mlk.rbac.Service.SysAclModuleService;
import com.mlk.rbac.dto.AclModuleTreeDTO;
import com.mlk.rbac.mapper.SysAclModuleMapper;
import com.mlk.rbac.po.SysAclModule;
import com.mlk.rbac.po.SysUser;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static java.util.Comparator.comparingInt;

/**
 * 系统模块服务
 * 
 * @author trek
 */
@Service
public class SysAclModuleServiceImpl implements SysAclModuleService {

	// 其中父节点的id为0
	public static final Integer DEFAULT_ROOT_ID = 0;

	@Resource
	private SysAclModuleMapper sysAclModuleMapper;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jieyun.rbac.service.SysAclModuleService#listAllModule()
	 * 配置了一个全能用户,这个用户帮助系统进行资源的分配.
	 */
	@Override
	public ServerResponse sysMenu() {
		SysUser sysUser = SessionUtils.getSysUser();
		Integer userId = null;
		//  超级管理员查看全部
		if(! Constant.SYSTEM_SUER.equals(sysUser.getUsername())) {
			userId = sysUser.getId();
		}
		List<SysAclModule> aclList = this.sysAclModuleMapper.sysMenu(userId);
		return ServerResponse.ok(listTree(aclList));
	}

	/**
	 * 树形化菜单内容
	 * 
	 * @param aclList
	 * @return
	 */
	private List<AclModuleTreeDTO> listTree(List<SysAclModule> aclList) {

		// 先转换为Dto的list
		List<AclModuleTreeDTO> dtoList = Lists.newArrayList();
		aclList.forEach(e -> {
			dtoList.add(AclModuleTreeDTO.adapt(e));
		});

		// 转换成MulitMap结构的内容
		ListMultimap<Integer, AclModuleTreeDTO> dtoMap = ArrayListMultimap.create();
		dtoList.forEach(e -> {
			dtoMap.put(e.getParentId(), e);
		});

		// 进行排序操作
		dtoMap.keySet().forEach(e -> {
			Collections.sort(dtoMap.get(e), comparingInt(SysAclModule::getSeq));
		});

		// 选出顶层的菜单内容
		List<AclModuleTreeDTO> rootList = dtoList.stream().filter(e -> {
			return e.getParentId() == DEFAULT_ROOT_ID;
		}).collect(Collectors.toList());

		// 下面开始递归完成树形化操作
		return doTree(dtoMap, rootList);
	}

	/**
	 * 递归操作
	 */
	private List<AclModuleTreeDTO> doTree(ListMultimap<Integer, AclModuleTreeDTO> dtoMap,
			List<AclModuleTreeDTO> rootList) {
		rootList.forEach(e -> {
			e.setChildren(dtoMap.get(e.getId()));
			doTree(dtoMap, e.getChildren());
		});
		return rootList;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jieyun.rbac.service.SysAclModuleService#list()
	 */
	@Override
	public List<SysAclModule> list() {
		return this.sysAclModuleMapper.selectList(new EntityWrapper<>(SysAclModule.builder().status(Constant.status_ok).build()));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jieyun.rbac.service.SysAclModuleService#delAcl(java.lang.Integer)
	 */
	@Override
	public ServerResponse delAcl(Integer id) {
		if (id == null) {
			return ServerResponse.fail("删除的权限id不能为空");
		}

		// 判断是否存在子节点
		if(existsSubNode(id)) {
			return ServerResponse.fail("该节点存在子节点");
		}
		
		//剩下的情况是可以删除该节点的
		SysAclModule acl = SysAclModule.builder().id(id).status(Constant.status_fail).build();
		
		int count = this.sysAclModuleMapper.updateById(acl);
		if(count ==0) {
			return ServerResponse.fail("删除权限失败");
		}
		return ServerResponse.ok("删除权限成功");
	}

	/**
	 * 判断是否存在子节点
	 * 
	 * @param id
	 * @return
	 */
	private boolean existsSubNode(Integer id) {
		return this.sysAclModuleMapper.selectCount(
				new EntityWrapper<>(SysAclModule.builder().parentId(id).status(Constant.status_ok).build())) != 0;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.jieyun.rbac.service.SysAclModuleService#aclAdd(com.jieyun.rbac.po.SysAclModule)
	 */
	@Override
	public ServerResponse aclAdd(SysAclModule acl) {
		if(acl == null) {
			throw new ParamException("没有传入权限参数");
		}
		int count = 0;

		if(acl.getId() == null) {
			acl.setOperator(SessionUtils.getSysUser().getName());
			acl.setOperateTime(new Date());
			count  = this.sysAclModuleMapper.insert(acl);
		}

		if(count == 0){
			return ServerResponse.fail("添加新权限失败");
		}
		return ServerResponse.ok("权限添加成功");
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.jieyun.rbac.service.SysAclModuleService#aclUpdate(com.jieyun.rbac.po.SysAclModule)
	 */
	@Override
	public ServerResponse aclUpdate(SysAclModule acl) {
		if(acl == null) {
			return ServerResponse.fail("修改的权限不能为空");
		}
		
		if(acl.getId() == null) {
			return ServerResponse.fail("修改的权限id不能为空");
		}
		// 更新操作者
		acl.setOperateTime(new Date());
		acl.setOperator(SessionUtils.getSysUser().getName());
		int count = this.sysAclModuleMapper.updateById(acl);
		
		if(count == 0) {
			return ServerResponse.fail("更新权限失败");
		}
		
		return ServerResponse.ok("更新权限成功");
	}

}
